﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Extensions.LinqExtension
{
    public static class LinqExtensions
    {
        /// <summary>
        /// Returns the Item after a specified Index as an Integer.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="index"></param>
        /// <param name="item"></param>
        /// <returns></returns>
        public static T FindFirstAfterIndex<T>(this IEnumerable<T> list, int index, T item)
        {
            return FindFirstAfterIndex(list, index, item, EqualityComparer<T>.Default);
        } 

        /// <summary>
        /// Returns the Item after a specified Index and specified EqualityComparer.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="index"></param>
        /// <param name="item"></param>
        /// <param name="comparer"></param>
        /// <returns></returns>
        public static T FindFirstAfterIndex<T>(this IEnumerable<T> list, int index, T item, IEqualityComparer<T> comparer)
        {
            return list.Skip(index).Where(result => comparer.Equals(result, item)).First(); 
        }

        /// <summary>
        /// Returns the Item after a specified Index as an Item.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="index"></param>
        /// <param name="item"></param>
        /// <returns></returns>
        public static T FindFirstAfterIndex<T>(this IEnumerable<T> list, T index, T item)
        {
            return FindFirstAfterIndex(list, list.IndexOf(item), item, EqualityComparer<T>.Default);
        }


        /// <summary>
        /// Returns the Index as Integer of a specified Item.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static int IndexOf<T>(this IEnumerable<T> obj, T value)
        {
            return obj.IndexOf(value, null);
        }


        /// <summary>
        /// Returns the Index as Integer of a specified Item and specified EqualityComparer.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <param name="value"></param>
        /// <param name="comparer"></param>
        /// <returns></returns>
        public static int IndexOf<T>(this IEnumerable<T> obj, T value, IEqualityComparer<T> comparer)
        {
            comparer = comparer ?? EqualityComparer<T>.Default;
            var found = obj
                .Select((a, i) => new { a, i })
                .FirstOrDefault(x => comparer.Equals(x.a, value));
            return found == null ? -1 : found.i;
        } 


    }
}
